package com.github.mzule.fantasyslide.app;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;

import com.github.mzule.fantasyslide.util.Base64Util;
import com.github.mzule.fantasyslide.util.CrashUtil;
import com.github.mzule.fantasyslide.util.HCNetSDKJNAInstance;
import com.github.mzule.fantasyslide.util.OkHttpUtil;
import com.github.mzule.fantasyslide.util.PlaySurfaceView;
import com.hikvision.netsdk.ExceptionCallBack;
import com.hikvision.netsdk.HCNetSDK;
import com.hikvision.netsdk.NET_DVR_DEVICEINFO_V30;
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO;
import com.hikvision.netsdk.StdDataCallBack;

import android.support.v4.app.ActivityCompat;


import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by zhou on 2019-01-23.
 */

public class ViewActivity extends BaseActivity implements SurfaceHolder.Callback {
    private String ip = null;
    private String port = null;
    private String user = null;
    private String password = null;
    private Button m_oSearchBtn = null;
    private Button m_oPlayBtn = null;
    private SurfaceView m_osurfaceView = null;
    private final static int REQUEST_CODE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};



    private NET_DVR_DEVICEINFO_V30 m_oNetDvrDeviceInfoV30 = null;
    private StdDataCallBack cbf = null;

    private int m_iLogID = -1; // return by NET_DVR_Login_v30
    private int m_iPlayID = -1; // return by NET_DVR_RealPlay_V40
    private int m_iPlaybackID = -1; // return by NET_DVR_PlayBackByTime

    private int m_iStartChan = 0; // start channel number
    private int m_iChanNum = 0; // channel number
    private static PlaySurfaceView[] playView = new PlaySurfaceView[4];

    private final String TAG = "ViewActivity";

    private boolean m_bTalkOn = false;
    private boolean m_bPTZL = false;
    private boolean m_bMultiPlay = false;
    private boolean m_bSaveRealData = false;
    private boolean m_bStopPlayback = false;
    private boolean m_bPlaybackByName = false;
    private String m_retUrl = "";

    public static String accessToken = "";
    public static String areaDomain = "";
    public static String appkey = ""; // fill in with appkey
    public static String appSecret = ""; // fill in with appSecret

    public ViewActivity view;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState)
    {
        setContentView(R.layout.view);
        super.onCreate(savedInstanceState);
        CrashUtil crashUtil = CrashUtil.getInstance();
        crashUtil.init(this);


        if (!initeSdk())
        {
            this.finish();
            return;
        }

        if (!initeActivity())
        {
            this.finish();
            return;
        }
        Bundle bundle = getIntent().getExtras();
        ip = bundle.getString("ip");
        port = bundle.getString("port");
        user = bundle.getString("user");
        password =  bundle.getString("password");
        try {
            if (m_iLogID < 0)
            {
                // login on the device
                m_iLogID = loginDevice();
                if (m_iLogID < 0)
                {
                    return;
                }
                else
                {
                }
                // get instance of exception callback and set
                ExceptionCallBack oexceptionCbf = getExceptiongCbf();
                if (oexceptionCbf == null)
                {
                    return;
                }

                if (!HCNetSDK.getInstance().NET_DVR_SetExceptionCallBack(oexceptionCbf))
                {
                    return;
                }

            }
            else
            {

                m_iLogID = -1;
            }

        }
        catch (Exception err)
        {
        }

    }

    // @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        m_osurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

        //valid just when single channel preview
        if (-1 == m_iPlayID && -1 == m_iPlaybackID)
        {
            return;
        }
        playView[0].m_hHolder = holder;
        Surface surface = holder.getSurface();
        if (true == surface.isValid())
        {
            if(m_iPlayID != -1)
            {
                if (-1 == HCNetSDK.getInstance().NET_DVR_RealPlaySurfaceChanged(m_iPlayID, 0, holder))
                {
                }
            }
            else
            {
                if (-1 == HCNetSDK.getInstance().NET_DVR_PlayBackSurfaceChanged(m_iPlaybackID, 0, holder))
                {
                }
            }

        }
    }

    // @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
    }

    // @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        if (-1 == m_iPlayID && -1 == m_iPlaybackID)
        {
            return;
        }
        if (true == holder.getSurface().isValid())
        {
            if(m_iPlayID != -1)
            {
                if (-1 == HCNetSDK.getInstance().NET_DVR_RealPlaySurfaceChanged(m_iPlayID, 0, null))
                {
                }
            }
            else
            {
                if (-1 == HCNetSDK.getInstance().NET_DVR_PlayBackSurfaceChanged(m_iPlaybackID, 0, null))
                {
                }
            }
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        outState.putInt("m_iPlayID", m_iPlayID);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState)
    {
        m_iPlayID = savedInstanceState.getInt("m_iPlayID");
        super.onRestoreInstanceState(savedInstanceState);
    }

    /**
     * @fn initeSdk
     * @author zhuzhenlei
     * @brief SDK init
     *            [in]
     *            [out]
     * @return true - success;false - fail
     */
    private boolean initeSdk()
    {
        // init net sdk
        if (!HCNetSDK.getInstance().NET_DVR_Init())
        {
            return false;
        }
        HCNetSDK.getInstance().NET_DVR_SetLogToFile(3, "/mnt/sdcard/sdklog/", true);
        return true;
    }

    // GUI init
    private boolean initeActivity()
    {
        findViews();
        m_osurfaceView.getHolder().addCallback(this);
        setListeners();
        return true;
    }

    private void ChangeSingleSurFace(boolean bSingle)
    {
        DisplayMetrics metric = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metric);

        for (int i = 0; i < 4; i++)
        {
            if (playView[i] == null)
            {
                playView[i] = new PlaySurfaceView(this);
                playView[i].setParam(metric.widthPixels);
                FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                        FrameLayout.LayoutParams.WRAP_CONTENT,
                        FrameLayout.LayoutParams.WRAP_CONTENT);
                params.bottomMargin = playView[i].getM_iHeight() - (i / 2)
                        * playView[i].getM_iHeight();
                params.leftMargin = (i % 2) * playView[i].getM_iWidth();
                params.gravity = Gravity.TOP | Gravity.LEFT;
                addContentView(playView[i], params);
                playView[i].setVisibility(View.INVISIBLE);

            }
        }

        if (bSingle)
        {
            for (int i = 0; i < 4; ++i)
            {
                playView[i].setVisibility(View.INVISIBLE);
            }
            playView[0].setParam(metric.widthPixels * 2);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            params.bottomMargin = playView[3].getM_iHeight() - (3 / 2)
                    * playView[3].getM_iHeight();
//            params.bottomMargin = 0;
            params.leftMargin = 0;
            // params.
            params.gravity = Gravity.TOP | Gravity.LEFT;
            playView[0].setLayoutParams(params);
            playView[0].setVisibility(View.VISIBLE);
        }
        else
        {
            for (int i = 0; i < 4; ++i)
            {
                playView[i].setVisibility(View.VISIBLE);
            }

            playView[0].setParam(metric.widthPixels);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            params.bottomMargin = playView[0].getM_iHeight() - (0 / 2)
                    * playView[0].getM_iHeight();
            params.leftMargin = (0 % 2) * playView[0].getM_iWidth();
            params.gravity = Gravity.BOTTOM | Gravity.LEFT;
            playView[0].setLayoutParams(params);
        }
    }
    private void findViews()
    {
        m_oSearchBtn = (Button) findViewById(R.id.btn_Search);
        m_oPlayBtn = (Button) findViewById(R.id.btn_Play);
        m_osurfaceView = (SurfaceView) findViewById(R.id.View_Player);
    }

    // listen
    private void setListeners()
    {
        m_oSearchBtn.setOnClickListener(Search_Listener);
        m_oPlayBtn.setOnClickListener(Play_Listener);
    }
    private Button.OnClickListener Play_Listener = new View.OnClickListener()
    {
        public void onClick(View v)
        {

            try
            {
                if (m_iLogID < 0)
                {
                    Log.e(TAG, "please login on device first");

                    return;
                }

                if (m_iPlaybackID >= 0)
                {
                    Log.i(TAG, "Please stop palyback first");

                    return;
                }

                if (m_iChanNum > 1)// preview more than a channel
                {
                    if (!m_bMultiPlay)
                    {
                        startMultiPreview();
                        m_bMultiPlay = true;
                        m_oSearchBtn.setVisibility(View.VISIBLE);
                        m_oPlayBtn.setText("停止");

                    }
                    else
                    {
                        stopMultiPreview();
                        m_bMultiPlay = false;
                        m_oSearchBtn.setVisibility(View.INVISIBLE);
                        m_oPlayBtn.setText("开始预览");
                    }
                }
                else // preivew a channel
                {
                    if (m_iPlayID < 0)
                    {
                        startSinglePreview();
                        m_oSearchBtn.setVisibility(View.VISIBLE);
                        m_oPlayBtn.setText("停止");
                    }
                    else
                    {
                        m_oSearchBtn.setVisibility(View.INVISIBLE);
                        m_oPlayBtn.setText("开始预览");
                        stopSinglePreview();
                    }
                }
            }
            catch(Exception ex) {
                Log.e(TAG, ex.toString());
            }
        }
    };


    private Button.OnClickListener Search_Listener = new View.OnClickListener()
    {
        public void onClick(View v)
        {
            m_oSearchBtn.setText("请稍等...");
            if (m_iPlayID < 0 && m_iPlaybackID < 0) {
                new AlertDialog.Builder(ViewActivity.this)
                        .setTitle("提示")//标题
                        .setMessage("抓图失败，请再次尝试")//内容
                        .create();
                m_oSearchBtn.setText("比对");
            }
            if (m_iPlayID >= 0) {
                if (ActivityCompat.checkSelfPermission(ViewActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(ViewActivity.this, PERMISSIONS_STORAGE, REQUEST_CODE);//requesrCode
                } else {
                    Log.d(TAG, "已有权限");
                    HCNetSDKJNAInstance.getInstance().NET_DVR_SetCapturePictureMode(1);
                    HCNetSDKJNAInstance.getInstance().NET_DVR_CapturePictureBlock(m_iPlayID, "/sdcard/capblock.jpg", 0);

                    String image = Base64Util.imageToBase64("/sdcard/capblock.jpg");
                    Map<String, Object> map = new HashMap<>();
                    map.put("groupIdList", "1234");
                    map.put("image", image);
                    map.put("imageType", "BASE64");
                    map.put("livenessControl", "LOW");
                    map.put("maxUserNum", "1");
                    map.put("qualityControl", "LOW");
                    OkHttpUtil.post("http://192.168.1.188:9090/middleware/baiduFace/search", map);
                    OkHttpUtil.handler = new Handler() {
                        @Override
                        public void handleMessage(Message msg) {
                            super.handleMessage(msg);
                            Bundle data = msg.getData();
                            String responseData = data.getString("responseData") == null ? data.getString("errorMessage") : data.getString("responseData");
                            m_oSearchBtn.setText("比对");
                            //Log.e("ttttttttttt1234", responseData);
                            try {
                                JSONObject jsonObject = new JSONObject(responseData);
                                if(jsonObject.getString("code").equals("0")){
                                    // Log.e("code*****", jsonObject.getString("data"));
                                    Intent intent = new Intent(ViewActivity.this, InfoActivity.class);

                                    Bundle bundle = new Bundle();
                                    JSONObject baiduFaceInfo = jsonObject.getJSONObject("data").getJSONObject("result").getJSONArray("user_list").getJSONObject(0);

                                    JSONObject blastCardInfo = jsonObject.getJSONObject("blastCardInfo");
                                    String avatar =  blastCardInfo.getString("avatar");
                                    String name = blastCardInfo.getString("name");
                                    String sex = blastCardInfo.getInt("sex")==0?"男":"女";
                                    String idCard = blastCardInfo.getString("idCard");
                                    String workplace = blastCardInfo.getString("workplace");
                                    Double score = baiduFaceInfo.getDouble("score");
                                    if(score>=80) {
                                        bundle.putString("avatar", avatar);
                                        bundle.putString("name", name);
                                        bundle.putString("sex", sex);
                                        bundle.putString("idCard", idCard);
                                        bundle.putString("workplace", workplace);
                                        bundle.putString("score", score.toString());
                                        intent.putExtras(bundle);
                                        startActivity(intent);
                                    }else{
                                        new AlertDialog.Builder(ViewActivity.this)
                                                .setTitle("提示")//标题
                                                .setMessage("没有找到此人信息")//内容
                                                .create().show();
                                    }
                                }

                                else{
                                    new AlertDialog.Builder(ViewActivity.this)
                                            .setTitle("提示")//标题
                                            .setMessage(responseData)//内容
                                            .create().show();

                                    //       Toast.makeText(ViewActivity.this, String.valueOf(response.body()), Toast.LENGTH_SHORT).show();
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    };
                }
            }


        }
    };
    private Button.OnClickListener Back_Listener = new View.OnClickListener()
    {
        public void onClick(View v)
        {
            // whether we have logout
            if (!HCNetSDK.getInstance().NET_DVR_Logout_V30(m_iLogID))
            {
                //if (!HCNetSDKJNAInstance.getInstance().NET_DVR_DeleteOpenEzvizUser(m_iLogID)) {
                //		Log.e(TAG, " NET_DVR_DeleteOpenEzvizUser is failed!");
                return;
            }
            Intent intent = new Intent(ViewActivity.this, MenuActivity.class);
            reset();
            startActivity(intent);
            finish();

        }
    };
    private void reset(){
        m_iLogID = -1; // return by NET_DVR_Login_v30
        m_bMultiPlay = false;
        m_iStartChan = 0; // start channel number
        m_iChanNum = 0; // channel number
        stopMultiPreview();
        playView = new PlaySurfaceView[4];
        stopSinglePreview();
    }

    private void startMultiPreview()
    {
        //one by one
        for (int i = 0; i < 4; i++)
        {
            playView[i].startPreview(m_iLogID, m_iStartChan + i);
        }
    }
    private void stopMultiPreview()
    {
        int i = 0;
        for (i = 0; i < 4; i++)
        {
            playView[i].stopPreview();
        }
        m_iPlayID = -1;
    }
    private void startSinglePreview()
    {
        if (m_iPlaybackID >= 0)
        {
            return;
        }


        NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();
        previewInfo.lChannel = m_iStartChan;
        previewInfo.dwStreamType = 0; // main stream
        previewInfo.bBlocked = 1;
        previewInfo.hHwnd = playView[0].m_hHolder;

        m_iPlayID = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(m_iLogID, previewInfo, null);
        if (m_iPlayID < 0)
        {
            return;
        }

        /* open sound
        boolean bRet = HCNetSDKJNAInstance.getInstance().NET_DVR_OpenSound(m_iPlayID);
        if(bRet)
        {
        	Log.e(TAG, "NET_DVR_OpenSound Succ!");
        }
        */

        /* capture picture
        if(HCNetSDKJNAInstance.getInstance().NET_DVR_CapturePicture(m_iPlayID, "/mnt/sdcard/capture_01.dmp"))
        {
        	Log.e(TAG, "NET_DVR_CapturePicture Succ!");
        }
        else
        {
        	Log.e(TAG, "NET_DVR_CapturePicture fail! Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
        }
        */

        /* set volume
        short volume = 55;
        if(HCNetSDKJNAInstance.getInstance().NET_DVR_Volume(m_iPlayID, volume))
        {
        	Log.e(TAG, "NET_DVR_Volume Succ!");
        }
        */

        /* std data call back
        if(cbf == null)
        {
            cbf = new StdDataCallBack()
            {
                public void fStdDataCallback(int iRealHandle, int iDataType, byte[] pDataBuffer, int iDataSize)
                {
                    //handle stream data
                }

            };
         }

         if(!HCNetSDK.getInstance().NET_DVR_SetStandardDataCallBack(m_iPlayID, cbf))
         {
             Log.e(TAG, "NET_DVR_SetStandardDataCallBack is failed!Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());

         }
         else
         {
        	 Log.i(TAG, "NET_DVR_SetStandardDataCallBack sucess");
         }
         */
    }

    private void stopSinglePreview()
    {
        if (m_iPlayID < 0)
        {
            return;
        }

        if(HCNetSDKJNAInstance.getInstance().NET_DVR_CloseSound())
        {
        }

        // net sdk stop preview
        if (!HCNetSDK.getInstance().NET_DVR_StopRealPlay(m_iPlayID))
        {
            return;
        }
        m_iPlayID = -1;
    }
    private int loginDevice()
    {
        int iLogID = -1;
        iLogID = loginNormalDevice();
        // iLogID = JNATest.TEST_EzvizLogin();
        // iLogID = loginEzvizDevice();
        return iLogID;
    }
    private int loginNormalDevice()
    {
        Intent intent = new Intent(ViewActivity.this, MenuActivity.class);

        // get instance
        m_oNetDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();
        Bundle backBundle = new Bundle();
        if (null == m_oNetDvrDeviceInfoV30)
        {
            return -1;
        }

        // call NET_DVR_Login_v30 to login on, port 8000 as default
        int iLogID = HCNetSDK.getInstance().NET_DVR_Login_V30(ip, Integer.parseInt(port), user, password, m_oNetDvrDeviceInfoV30);
        if (iLogID < 0)
        {
            Log.e(TAG, "NET_DVR_Login is failed!Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
            backBundle.putInt("code",-1);
            intent.putExtras(backBundle);
            startActivity(intent);
            this.finish();
            return -1;
        }

        if (m_oNetDvrDeviceInfoV30.byChanNum > 0)
        {
            m_iStartChan = m_oNetDvrDeviceInfoV30.byStartChan;
            m_iChanNum = m_oNetDvrDeviceInfoV30.byChanNum;
        }
        else if (m_oNetDvrDeviceInfoV30.byIPChanNum > 0)
        {
            m_iStartChan = m_oNetDvrDeviceInfoV30.byStartDChan;
            m_iChanNum = m_oNetDvrDeviceInfoV30.byIPChanNum + m_oNetDvrDeviceInfoV30.byHighDChanNum * 256;
        }

        if (m_iChanNum > 1)
        {
            ChangeSingleSurFace(false);
        }
        else
        {
            ChangeSingleSurFace(true);
        }
        Log.i(TAG, "NET_DVR_Login is Successful!");
        return iLogID;
    }
    private ExceptionCallBack getExceptiongCbf()
    {
        ExceptionCallBack oExceptionCbf = new ExceptionCallBack()
        {
            public void fExceptionCallBack(int iType, int iUserID, int iHandle)
            {
                System.out.println("recv exception, type:" + iType);
            }
        };
        return oExceptionCbf;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,  int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE) {
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == 0) {
                    Log.d(TAG, "获取权限成功");
//                    perSucceed();
                    HCNetSDKJNAInstance.getInstance().NET_DVR_SetCapturePictureMode(1);
                    HCNetSDKJNAInstance.getInstance().NET_DVR_CapturePictureBlock(m_iPlayID, "/sdcard/capblock.jpg", 0);

                    String image = Base64Util.imageToBase64("/sdcard/capblock.jpg");
                    Map<String, Object> map = new HashMap<>();
                    map.put("groupIdList", "1234");
                    map.put("image", image);
                    map.put("imageType", "BASE64");
                    map.put("livenessControl", "LOW");
                    map.put("maxUserNum", "1");
                    map.put("qualityControl", "LOW");
                    OkHttpUtil.post("http://192.168.1.188:9090/middleware/baiduFace/search", map);
                    OkHttpUtil.handler = new Handler() {
                        @Override
                        public void handleMessage(Message msg) {
                            super.handleMessage(msg);
                            Bundle data = msg.getData();
                            String responseData = data.getString("responseData") == null ? data.getString("errorMessage") : data.getString("responseData");
                            m_oSearchBtn.setText("比对");
                            //Log.e("ttttttttttt1234", responseData);
                            try {
                                JSONObject jsonObject = new JSONObject(responseData);
                                if(jsonObject.getString("code").equals("0")){
                                    // Log.e("code*****", jsonObject.getString("data"));
                                    Intent intent = new Intent(ViewActivity.this, InfoActivity.class);

                                    Bundle bundle = new Bundle();
                                    JSONObject baiduFaceInfo = jsonObject.getJSONObject("data").getJSONObject("result").getJSONArray("user_list").getJSONObject(0);

                                    JSONObject blastCardInfo = jsonObject.getJSONObject("blastCardInfo");
                                    String avatar =  blastCardInfo.getString("avatar");
                                    String name = blastCardInfo.getString("name");
                                    String sex = blastCardInfo.getInt("sex")==0?"男":"女";
                                    String idCard = blastCardInfo.getString("idCard");
                                    String workplace = blastCardInfo.getString("workplace");
                                    Double score = baiduFaceInfo.getDouble("score");
                                    if(score>=80) {
                                        bundle.putString("avatar", avatar);
                                        bundle.putString("name", name);
                                        bundle.putString("sex", sex);
                                        bundle.putString("idCard", idCard);
                                        bundle.putString("workplace", workplace);
                                        bundle.putString("score", score.toString());
                                        intent.putExtras(bundle);
                                        startActivity(intent);
                                    }else{
                                        new AlertDialog.Builder(ViewActivity.this)
                                                .setTitle("提示")//标题
                                                .setMessage("没有找到此人信息")//内容
                                                .create().show();
                                    }
                                }

                                else{
                                    new AlertDialog.Builder(ViewActivity.this)
                                            .setTitle("提示")//标题
                                            .setMessage(responseData)//内容
                                            .create().show();

                                    //       Toast.makeText(ViewActivity.this, String.valueOf(response.body()), Toast.LENGTH_SHORT).show();
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    };
                } else {
                    Log.d(TAG, "获取权限失败");
//                    ToastUtils.showToast(mContext, "权限被拒绝,连接USB设备终止");
                }
            }
        }
    }

}
